// run: $exec < input
// opt: 0
// flag: -g
#include <iostream>
#include <algorithm>
#include <vector>
#include <unordered_map>

struct query { int l, r, id; };
std::vector<query> q;

int const maxn = 100007;
int const size = 317;
std::unordered_map<int, int> count;
int a[maxn];
int n, m;
long long ans[maxn];
long long cur_ans = 0;

bool mo_cmp(query const & a, query const & b)
{
	if (a.l / size != b.l / size) return a.l / size < b.l / size;
	else return (a.r < b.r) ^ ((a.l / size) & 1); // faster
//	else return a.r < b.r;
}

void mo_add(int x)
{
	if (!x) return;
	if (count[x]++ == x) cur_ans--;
	if (count[x] == x) cur_ans++;
}

void mo_remove(int x)
{
	if (!x) return;
	if (count[x]-- == x) cur_ans--;
	if (count[x] == x) cur_ans++;
}

int main()
{
	std::ios::sync_with_stdio(false);
	std::cin >> n >> m;
	for (int i = 1; i <= n; i++) std::cin >> a[i];
	q.resize(m);
	for (int i = 0; i < m; i++) {
		std::cin >> q[i].l >> q[i].r;
		q[i].id = i;
	}
	std::sort(q.begin(), q.end(), mo_cmp);
	int l = 0, r = 0;
	for (auto i : q) {
		while (l < i.l) mo_remove(a[l++]);
		while (l > i.l) mo_add(a[--l]);
		while (r > i.r) mo_remove(a[r--]);
		while (r < i.r) mo_add(a[++r]);
		ans[i.id] = cur_ans;
	}
	for (int i = 0; i < m; i++)
		std::cout << ans[i] << '\n';

}

